

import pygtk
pygtk.require('2.0')
import gtk
import pango

import _emulator
from _icon import Icon

class Listbox:
    """An instance of this UI control type is visible as a listbox, also known as a list in Symbian, that can be
    configured to be a single-line item or a double-item listbox.
    """
    def __init__(self, items, callback):
        """  Creates a Listbox instance. A callable object callback gets called when a listbox selection
        has been made. items defines the content of the listbox and can be one of the following:
        A normal (single-line item) listbox: a list of Unicode strings, for example [unicode_string
        item1, unicode_string item2]
        o A double-item listbox: a two-element tuple of Unicode strings , for example
        [(unicode_string item1, unicode_string item1description),
        (unicode_string item2, unicode_string item2description)]
        o A normal (single-line item) listbox with graphics: a two-element tuple consisting of a Unicode
        string and an Icon object, for example [(unicode_string item1, icon1),
        (unicode_string item2, icon2)].
        o A double-item listbox with graphics: a three-element tuple consisting of two Unicode strings
        and one Icon object, for example [(unicode_string item1, unicode_string
        item1description, icon1), (unicode_string item2, unicode_string
        item2description, icon2)]
        """
	self._callback = callback
	self._bindings = {}

	self._ctrl = wx.ListCtrl(_wxinit._frame, -1, style=wx.LC_REPORT | wx.LC_NO_HEADER | wx.LC_SINGLE_SEL)
        self._ctrl.InsertColumn(0, "")
        self._double = False
	self._ctrl.Bind(wx.EVT_KEY_DOWN, self._OnKeyDown)
        self._ctrl.Bind(wx.EVT_SIZE, self._OnSize)
        self._ctrl.Bind(wx.EVT_LIST_ITEM_ACTIVATED, self._OnSelect, self._ctrl)
        

	self.set_list(items)

    def bind(self, event_code, callback):
        """Binds the callable Python object callback to event event_code. The key codes are defined
        in the key_codes library module. The call bind(event_code, None) clears an existing
        binding. In the current implementation the event is always passed also to the underlying native
        UI control.
        """
        code = event_code #key_mappings.get(key)
        if code is not None:
            self._bindings[code] = callback

    def current(self):
        """Returns the currently selected item's index in the Listbox."""
        index = self._ctrl.GetFirstSelected()
        if index < 0:
            index = 0
        return index

    def set_list(self, items, current = 0):
        """ Sets the Listbox content to a list of Unicode strings or a list of tuples of Unicode strings. items
        can be one of the following:
        o A normal (single-style) list: a list of Unicode strings, for example [unicode_string
        item1, unicode_string item2]
        o A double-style list box: a two-element tuple of Unicode strings , for example
        [(unicode_string item1, unicode_string item1description),
        (unicode_string item2, unicode_string item2description)]
        o A normal (single-style) list with graphics: a two-element tuple consisting of a Unicode string
        and an Icon object, for example [(unicode_string item1, icon1),
        (unicode_string item2, icon2)].
        o A double-style list box with graphics: a three-element tuple consisting of two Unicode strings
        and one Icon object, for example [(unicode_string item1, unicode_string
        item1description, icon1), (unicode_string item2, unicode_string
        item2description, icon2)]
        Optionally, the initially focused list item can be set.
        """
        self._ctrl.DeleteAllItems()

        double = False
        iconElem = None

        if len(items) > 0:
            item = items[0]
            if isinstance(item, tuple):
                if len(item) == 3:
                    double= True
                    iconElem = 2
                elif isinstance(item[1], Icon):
                    iconElem = 1
                else:
                    double = True

        if double and not self._double:
            self._double = True
            self._ctrl.InsertColumn(1, "")
        elif self._double and not double:
            self._double = false
            self._ctrl.DeleteColumn(1)

#	iconList = wx.ImageList()
        for i in range(len(items)):
            item = items[i]

            if iconElem:
                self._ctrl.InsertImageStringItem(i, item[0], i)
            elif double:
                self._ctrl.InsertStringItem(i, item[0])
            else:
                self._ctrl.InsertStringItem(i, item)

            if double:
                self._ctrl.SetStringItem(i, 1, item[1], -1)

        self._ctrl.Select(current ,True)
        self._UpdateColumnsSize()

    def _OnKeyDown(self, event):
        code = event.GetKeyCode()
        cb = self._bindings.get(code)
        if cb is not None:
            cb()
        event.Skip()

    def _OnSize(self, event):
        self._UpdateColumnsSize()
        event.Skip()

    def _UpdateColumnsSize(self):
        w = self._ctrl.GetClientSize().width
        c = self._ctrl.GetColumnCount()
        for i in range(c):
            self._ctrl.SetColumnWidth(i, w/c)

    def _OnSelect(self, event):
        self._callback()

